local StoryActuator = class("StoryActuator")
local GameUtils = require("utils.GameUtils")
local StoryParser = require("gameLogic.story.StoryParser")

function StoryActuator:create(story)
    local gameObject = GameUtils.InstantiateEmptyObject("StoryActuator")
    local storyCamera = GameUtils.InstantiateEmptyObject("StoryCamera")
    local camera = storyCamera:AddComponent(typeof(CS.UnityEngine.Camera))
    camera.cullingMask = CS.UnityEngine.LayerMask.GetMask("UI") + CS.UnityEngine.LayerMask.GetMask("Default")
    GameUtils.addChildTo(gameObject.transform, storyCamera.transform)
    local luaBehaviour = gameObject:AddComponent(typeof(CS.LuaBehaviour))
    local newInstance = StoryActuator.new(story)
    newInstance:setStoryCamera(storyCamera)
    luaBehaviour:SetScriptEnv(newInstance)
    return newInstance
end

function StoryActuator:ctor(story)
    self._story = story
    self._heroMaps = {}
    self._appendObj = {}
end

function StoryActuator:setStoryCamera(camera)
    self._storyCamera = camera
end

function StoryActuator:getStoryCamera()
    return self._storyCamera
end

function StoryActuator:start()
    if type(self._story) == "string" then
        self._storyTree = StoryParser.parse(self._story, self)
    else
        self._storyTree = StoryParser.parseObj(self._story, self)
    end
    if self._storyTree then
        self._storyTree:tick()
        self._player = GameUtils.find("Player")
        self._mainCamera = GameUtils.getMainCamera()
        self:setPlayerActive(false)
    end
end

function StoryActuator:update()
    if not self._storyTree then
        return
    end
    if not self._storyTree:isDone() then
        self._storyTree:tick()
    else
        self:setPlayerActive(true)
        GameUtils.destroy(self.gameObject)
    end
end

function StoryActuator:addHero(heroRes, pos, heroName)
    local hero = self._heroMaps[heroName]
    if not hero then
        local heroPrefab = G_ResourceManager:loadActor(heroRes)
        hero = GameUtils.instantiateTo(self.transform, heroPrefab)
        -- GameUtils.changeGameObjectLayer(hero, 9)
        self._heroMaps[heroName] = hero
    end
    hero.transform.localPosition = pos
end

function StoryActuator:findHero(heroName)
    return self._heroMaps[heroName]
end

function StoryActuator:onDestroy()
    self._heroMaps = {}
    if type(self._story) == "userdata" then
        GameUtils.destroy(self._story)
    end
end

function StoryActuator:setPlayerActive(visible)
    if self._player then
        self._player:SetActive(visible)
    end
    if self._mainCamera then
        self._mainCamera.gameObject:SetActive(visible)
    end
end

return StoryActuator
